/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.webapp.action.core.actionPage;

import com.blandware.atleap.common.Constants;
import com.blandware.atleap.model.core.ActionPage;
import com.blandware.atleap.model.core.ContentField;
import com.blandware.atleap.model.core.ContentFieldValue;
import com.blandware.atleap.search.SearchManager;
import com.blandware.atleap.service.core.PageManager;
import com.blandware.atleap.service.exception.BeanAlreadyExistsException;
import com.blandware.atleap.webapp.action.core.BaseAction;
import com.blandware.atleap.webapp.form.core.ActionPageForm;
import com.blandware.atleap.webapp.util.core.CacheUtil;
import com.blandware.atleap.webapp.util.core.WebappConstants;
import com.blandware.atleap.webapp.util.core.WebappUtil;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.util.ModuleUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.List;

/**
 * <p>Creates new content actionPage
 * </p>
 * <p><a href="CreateActionPageAction.java.html"><i>View Source</i></a></p>
 * <p/>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @author Andrey Grebnev <a href="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
 * @version $Revision: 1.30 $ $Date: 2008/04/29 17:48:04 $
 * @struts.action name="actionPageForm"
 * path="/core/actionPage/create"
 * scope="request"
 * input="inputForward"
 * validate="true"
 * roles="core-actionPage-create"
 * @struts.action-forward name="inputForward"
 * path=".core.actionPage.create"
 * @struts.action-forward name="viewActionPage"
 * path="/core/actionPage/view.do"
 * redirect="true"
 * @struts.action-forward name="listActionPages"
 * path="/core/actionPage/list.do"
 * redirect="true"
 * @struts.action-forward name="unsatisfiable"
 * path="/core/actionPage/list.do"
 */
public final class CreateActionPageAction extends BaseAction {
	/**
	 * @param mapping  The ActionMapping used to select this instance
	 * @param form     The optional ActionForm bean for this request (if any)
	 * @param request  The HTTP request we are proceeding
	 * @param response The HTTP response we are creating
	 * @return an ActionForward instance describing where and how
	 *         control should be forwarded, or null if response
	 *         has already been completed
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form,
	                             HttpServletRequest request, HttpServletResponse response) throws Exception {

		if ( !isCancelled(request) ) {
			ActionPageForm actionPageForm = (ActionPageForm) form;

			if ( !WebappUtil.hasCorrectValues(actionPageForm.getTitleMap()) ) {
				// title must be specified
				ActionMessages errors = new ActionMessages();
				errors.add("title", new ActionMessage("core.commons.errors.required", getMessage(request, "core.page.form.title")));
				saveErrors(request, errors, false);
				saveToken(request);
				return mapping.getInputForward();
			}

			// check URI for existence
			String uri = actionPageForm.getUri();
			ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, getServlet().getServletContext());
			String prefix = moduleConfig.getPrefix();
			if ( log.isDebugEnabled() ) {
				log.debug("Prefix: " + prefix);
			}

			String actionPath = prefix + uri;

			if ( log.isDebugEnabled() ) {
				log.debug("Searching for action with path=" + actionPath);
			}

			if ( moduleConfig.findActionConfig(actionPath) == null ) {
				// action with this uri does not exist
				if ( log.isDebugEnabled() ) {
					log.debug("Action with uri '" + actionPath + "' does not exist");
				}
				ActionMessages errors = new ActionMessages();
				errors.add("actionPageIncorrectUri", new ActionMessage("core.actionPage.errors.incorrectUri"));
				saveErrors(request, errors);
				saveToken(request);
				return mapping.getInputForward();
			}

            ActionPage actionPage = new ActionPage();
			WebappUtil.copyProperties(actionPage, actionPageForm, request);
            WebappUtil.fillFieldValueWithDefaultLocaleValue(actionPageForm.getTitleMap(), actionPage.getTitle(), servlet.getServletContext());
            actionPage.setTitle(actionPageForm.getTitleMap());
            WebappUtil.copyFieldValue(actionPage.getDescription(), actionPageForm.getDescriptionMap());
            WebappUtil.copyFieldValue(actionPage.getKeywords(), actionPageForm.getKeywordsMap());

            PageManager pageManager = (PageManager) getBean(Constants.PAGE_MANAGER_BEAN);
			Long actionPageId;
			try {
				actionPageId = pageManager.createActionPage(actionPage);

				if ( actionPage.getActive().booleanValue() ) {
					//index action page
					SearchManager searchManager = SearchManager.getInstance(request.getSession().getServletContext());
					searchManager.reIndexPage(actionPage, request);
				}

				// put internal fields in cache 
				CacheUtil cacheUtil = CacheUtil.getInstance(request);

				// title
				ContentField titleField = (ContentField) actionPage.getContentFieldsMap().get("title");
				List titleValues = titleField.getContentFieldValues();
				for ( Iterator i = titleValues.iterator(); i.hasNext(); ) {
					ContentFieldValue fieldValue = (ContentFieldValue) i.next();
					// title field is single-lined
					String content = fieldValue.getSimpleValue();
					CacheUtil.CFVData cfvData = new CacheUtil.CFVData(content, titleField.getId(), titleField.getType(), fieldValue.getId(), actionPageId);
					cacheUtil.putPageFieldValueInCache(cfvData, actionPage.getUri(), titleField.getIdentifier(), fieldValue.getContentLocale().getIdentifier());
				}

				// description
				ContentField descriptionField = (ContentField) actionPage.getContentFieldsMap().get("description");
				List descriptionValues = descriptionField.getContentFieldValues();
				for ( Iterator i = descriptionValues.iterator(); i.hasNext(); ) {
					ContentFieldValue fieldValue = (ContentFieldValue) i.next();
					// description field is single-lined
					String content = fieldValue.getSimpleValue();
					CacheUtil.CFVData cfvData = new CacheUtil.CFVData(content, descriptionField.getId(), descriptionField.getType(), fieldValue.getId(), actionPageId);
					cacheUtil.putPageFieldValueInCache(cfvData, actionPage.getUri(), descriptionField.getIdentifier(), fieldValue.getContentLocale().getIdentifier());
				}

				// keywords
				ContentField keywordsField = (ContentField) actionPage.getContentFieldsMap().get("keywords");
				List keywordsValues = keywordsField.getContentFieldValues();
				for ( Iterator i = keywordsValues.iterator(); i.hasNext(); ) {
					ContentFieldValue fieldValue = (ContentFieldValue) i.next();
					// keywords field is single-lined
					String content = fieldValue.getSimpleValue();
					CacheUtil.CFVData cfvData = new CacheUtil.CFVData(content, keywordsField.getId(), keywordsField.getType(), fieldValue.getId(), actionPageId);
					cacheUtil.putPageFieldValueInCache(cfvData, actionPage.getUri(), keywordsField.getIdentifier(), fieldValue.getContentLocale().getIdentifier());
				}

			} catch ( BeanAlreadyExistsException e ) {
				// actionPage already exists
				ActionMessages errors = new ActionMessages();
				errors.add("actionPageAlreadyExists", new ActionMessage("core.actionPage.errors.alreadyExists"));
				saveErrors(request, errors);
				saveToken(request);
				return mapping.getInputForward();
			}
			request.getSession().setAttribute(WebappConstants.ACTION_PAGE_ID_KEY, actionPageId);
			return mapping.findForward("viewActionPage");
		} else {
			return mapping.findForward("listActionPages");
		}
	}
}